<!--
Date: 2025-08-13
Copyright (c) 2025 CAX Conversion Project
-->
<template>
  <el-dialog v-model="props.elementVisible" title="零件详情" width="1000" @close="handleVisible">
    <div class="element_view">
      <div class="top">
        <div class="title">零件号：{{ detailData?.partNumber }}</div>
        <div class="basic">
          <div class="item">
            <span>零件名称：</span>
            <span>{{ detailData?.name }}</span>
          </div>
          <div class="item">
            <span>机型：</span>
            <span>{{ detailData?.modelName }}</span>
          </div>
          <div class="item">
            <span>部段：</span>
            <span>{{ detailData?.sectionName }}</span>
          </div>
          <div class="item">
            <span>组件：</span>
            <span>{{ detailData?.componentNumber }}</span>
          </div>
        </div>
      </div>
      <el-divider style="margin: 0; margin-top: 10px" />
      <div class="info">
        <div class="left">
          <div class="title">版本号</div>
          <ul>
            <li v-for="item in version" :class="{ active: item.versionNumber === currentTab }" :key="item.versionNumber" @click="versionClick(item)">
              {{ item.versionNumber }} 版本
            </li>
          </ul>
        </div>
        <div class="right">
          <div class="top">
            <div>版本信息</div>
          </div>
          <el-divider style="margin: 0; margin-top: 10px" />
          <div class="basic">
            <div class="item">
              <span>版本号：</span>
              <span>{{ versionDetail?.versionNumber }}版本</span>
            </div>
            <div class="item">
              <span>单件重量：</span>
              <span>{{ versionDetail?.unitWeight }}<span v-if="versionDetail?.unitWeight">kg</span></span>
            </div>
            <div class="item">
              <span>数量：</span>
              <span>{{ versionDetail?.amount }}</span>
            </div>
            <div class="item">
              <span>材料：</span>
              <span>{{ versionDetail?.material }}</span>
            </div>
          </div>
          <div class="title">模型情况</div>
          <el-divider style="margin: 0; margin-top: 10px" />
          <el-tabs v-model="activeName" class="tabs" @tab-click="handleClick">
            <el-tab-pane label="模型预览" name="preView">
              <div style="width: 100%; height: 500px" v-loading="loading">
                <showThree
                  ref="threeRef"
                  :key="showThreeKey"
                  :model-info="modelInfo"
                  :shrink="threeShrink"
                  :showInfo="true"
                  @on-select="selectFn"
                  :selected-elements="selectElementFn"
                  @load-end="loadEnd"
                />
              </div>
            </el-tab-pane>
            <el-tab-pane label="BDF文件" name="bdf">
              <div class="bdf" v-loading="loading">
                <div class="bdf_search" v-if="searchVisible">
                  <el-input size="small" v-model.trim="searchContent" style="width: 140px" placeholder="请输入要查询的内容" />
                  <el-button type="primary" size="small" style="margin-left: 10px" @click="searchFn">搜索</el-button>
                  <el-button size="small" icon="Top" @click="preFn">上一个</el-button>
                  <el-button size="small" icon="Bottom" @click="nextFn">下一个</el-button>
                  <el-button size="small" icon="Close" @click="closeSearch">关闭</el-button>
                </div>
                <div style="width: 100%; max-height: 300px; overflow: auto" id="bdfContent" class="bdf_div"></div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button size="small" @click="handleVisible">关闭</el-button>
      </div>
    </template>
    <div id="bdfTmp" style="display: none"></div>
  </el-dialog>
</template>
<script setup name="ElementView">
import ShowThree from '@/components/ShowThree/index.vue';
import { getModelDetailById, queryBdfFileInfo, loadPartRender } from '@/api/elementsLibrary';

const props = defineProps(['elementVisible', 'data']);
const emit = defineEmits(['close']);
const showThreeKey = ref(0);
const modelInfo = ref({ url: '', userDataUrl: '' });
const threeShrink = ref(0);
const selectFn = () => {};
const selectElementFn = () => {};
const loadEnd = () => {};
const detailData = ref(null);
const versionDetail = ref(props?.data);
const renderList = ref([]);
const currentTab = ref(props?.data?.versionNumber);
const activeName = ref('preView');
const version = ref([]);
const loading = ref(false);
const searchVisible = ref(false);
const searchContent = ref();
//当前文本搜索的所有内容
const elements = ref([]);
// 搜索内容当前显示的位置索引
const currentSearchIndex = ref(0);

const handleVisible = () => {
  emit('close');
};
const handleClick = (e) => {
  activeName.value = e;
  if (e.props.name === 'bdf') {
    const params = {
      classification: 'model_management_part_data_prefix',
      uri: versionDetail.value.indexPath
    };
    loading.value = true;
    queryBdfFileInfo(params)
      .then((res) => {
        if (res) {
          const bdfDom = document.getElementById('bdfContent');
          const dom = document.getElementById('bdfTmp');
          if (dom) {
            dom.innerText = res;
            const splitArray = dom.innerHTML.split('<br>') || [];
            //CQUAD4开始下标
            let startIndex = splitArray.findIndex((item) => item.startsWith('CQUAD4'));
            //CQUAD4结束下标
            let endIndex = -1;
            for (let i = splitArray.length; i >= 0; i--) {
              const item = splitArray[i] || '';
              if (item.startsWith('CQUAD4')) {
                endIndex = i;
                break;
              }
            }
            // //将text内容转为html格式
            for (let i = 0; i < startIndex; i++) {
              splitArray[i] = `<div style="white-space:pre;">${splitArray[i]}</div>`;
            }
            for (let i = endIndex + 1; i < splitArray.length; i++) {
              splitArray[i] = `<div style="white-space:pre;">${splitArray[i]}</div>`;
            }
            for (let i = startIndex; i <= endIndex; i++) {
              splitArray[i] = setItemColor(splitArray[i]);
            }
            const bdfHtml = splitArray.join('');
            //dom展示
            bdfDom.innerHTML = bdfHtml;
          }
        }
      })
      .finally(() => {
        loading.value = false;
      });
  }
};
// 设置CQUAD4单元颜色
const setItemColor = (CQUAD4) => {
  if (!CQUAD4) {
    return;
  }
  let data = CQUAD4.split('  ');
  const colorArr = data.slice(1, data.length);
  const colorStr = colorArr.join('  ');
  const step = 8;
  const num = colorStr.length / step;
  let str = '';
  for (let i = 0; i < num; i++) {
    const color1 = '#d7d7d7';
    const color2 = '#f2f2f2';
    let color = '';
    let strItem = colorStr.slice(i * 8, (i + 1) * 8);
    //交替设置颜色
    if (i % 2 === 0) {
      color = color1;
    } else {
      color = color2;
    }
    str += `<span style="white-space:pre;width:54px;display: inline-block;background: ${color};">${strItem}</span>`;
  }
  const showStr = `<div style="white-space:pre;">${data[0]}&nbsp;&nbsp;${str}</div>`;
  return showStr;
};
const versionClick = (data) => {
  currentTab.value = data.versionNumber;
  versionDetail.value = data;
};
const closeSearch = () => {
  searchVisible.value = false;
};
const searchFn = () => {
  if (searchContent.value) {
    findText();
  }
};
// 下一个
const nextFn = () => {
  currentSearchIndex.value++;
  scrollToContent(currentSearchIndex.value);
};
// 上一个
const preFn = () => {
  currentSearchIndex.value--;
  scrollToContent(currentSearchIndex.value);
};
// 查找
const findText = async () => {
  const bdfDomHtml = document.getElementById('bdfContent').innerHTML;
  //先置空之前设置的样式
  const resetHtml1 = bdfDomHtml.replaceAll(`<span class="search_span" style="background:#bbd6fb;">`, ``);
  const resetHtml2 = resetHtml1.replaceAll(`</span>`, ``);
  const repalceStr = resetHtml2.replaceAll(searchContent.value, `<span class="search_span" style="background:#bbd6fb;">${searchContent.value}</span>`);
  document.getElementById('preViewContent').innerHTML = repalceStr;
  // 查找所有匹配selector的元素
  elements.value = document.querySelectorAll(`.search_span`) || [];
  if (elements.value.length === 0) {
    ElMessage({ showClose: true, message: '未检索到相关查询内容', type: 'waring' });
    return;
  }
  scrollToContent(0);
};
const scrollToContent = (index) => {
  // 默认滚动至第一条数据位置
  if (elements.value.length > 0) {
    if (elements.value[index]) {
      elements.value[index].scrollIntoView({ behavior: 'smooth' });
    }
  } else {
    ElMessage({ showClose: true, message: '未检索到相关查询内容', type: 'waring' });
  }
};
// 查询零件详情
const queryModelDetail = () => {
  getModelDetailById({ partNumber: props.data?.partNumber }).then((res) => {
    if (res) {
      detailData.value = res?.data;
      // 设置版本列表
      version.value = res?.data?.versionVoList || [];
    }
  });
};
// 查询模型预览
const loadRender = () => {
  loading.value = true;
  loadPartRender({ businessId: versionDetail.value.id, type: 'part' })
    .then(async (res) => {
      renderList.value = res.data;
      modelInfo.value.url = `/file${res?.data?.gltfPath}`;
      modelInfo.value.userDataUrl = `/file${res?.data?.xrefPath}`;
    })
    .finally(() => {
      loading.value = false;
    });
};
onMounted(() => {
  queryModelDetail();
  loadRender();
  window.addEventListener('keydown', function (e) {
    if (e.ctrlKey && e.key === 'f' && activeName.value === 'bdf') {
      e.preventDefault();
      searchVisible.value = true;
    }
  });
});
onUnmounted(() => {
  window.removeEventListener('keydown', function () {});
});
</script>
<style lang="scss" scoped>
.element_view {
  li {
    list-style: none;
    padding: 5px;
    cursor: pointer;
    width: 80px;
    text-align: center;
    font-size: 12px;
  }
  li:hover {
    background: #d9d9dd;
  }
  ul {
    margin: 0;
    padding: 0;
  }
  .top {
    .title {
      font-weight: 600;
    }
    .basic {
      display: flex;
      flex-wrap: wrap;
      .item {
        width: 300px;
        margin: 5px 0;
        font-size: 12px;
        > span:nth-child(2) {
          color: #909399;
        }
      }
    }
  }
  .info {
    height: 100%;
    display: flex;
    .left {
      width: 80px;
      padding-top: 10px;
      border-right: 1px solid #dcdfe6;
      .active {
        color: #409eff;
      }
    }
    .title {
      font-size: 12px;
    }
    .right {
      width: calc(100% - 80px);
      padding: 10px;
      .tabs {
        font-size: 12px;
      }
      .title {
        font-size: 12px;
        font-weight: 600;
        margin-top: 12px;
      }
      .top {
        display: flex;
        justify-content: space-between;
        > div {
          font-weight: 600;
          font-size: 12px;
        }
      }
      .basic {
        display: flex;
        flex-wrap: wrap;
        .item {
          width: 250px;
          margin: 5px 0;
          font-size: 12px;
          > span:nth-child(2) {
            color: #909399;
          }
        }
      }
    }
  }
  :deep(.el-tabs__item) {
    font-size: 12px;
  }
  .bdf {
    position: relative;
    width: 100%;
    max-height: 300px;
    display: flex;
    flex-direction: column;
    // align-items: end;
    .bdf_search {
      // width: 500px;
      position: sticky;
      top: 0;
      display: flex;

      border: 1px solid #e8e8e8;
      padding: 5px 10px;
      // border-radius: 10px;
      background: #fff;
    }
  }
}
</style>